#include"MainWindow.h" 

#include"PlayerController.h"
#include"LeftPane.h"
#include"PlaylistView.h"
#include"MetaDataDisplay.h"
#include"MetaDataEditor.h"
#include"SystemTrayIcon.h"
#include"Scrobbler.h"
#include"Settings.h"
#include"SettingsDialog.h"
#include"StatusBar.h"
#include"Playlist.h"
#include"PlaylistReader.h"
#include"PlaylistWriter.h"

#include<QPointer>

#include<stdio.h>

MainWindow::MainWindow():QMainWindow(0){
	setWindowTitle("Simple Qt Desktop Player");
	m_player = new Player(this);
	
	if(Settings::instance()->general->usePlaylist)
		PlaylistReader::read(m_player->playlist(), Settings::instance()->settingsDir() + ".playlist.xml");
	
	m_widget = new QWidget(this);
	m_layout = new QVBoxLayout(m_widget);
	m_widget->setLayout(m_layout);
	
	m_topWidget = new QWidget(m_widget);
	m_layout->addWidget(m_topWidget);
	
	m_topLayout = new QHBoxLayout(m_topWidget);
	m_topWidget->setLayout(m_topLayout);
	printf("a\n");
	_initPlayerController();
	printf("b\n");
	//_initScrobbler();
	printf("c\n");
	m_displayWidget = new QWidget(m_widget);
	m_layout->addWidget(m_displayWidget);
	
	m_displayLayout = new QHBoxLayout(m_displayWidget);
	m_displayWidget->setLayout(m_displayLayout);
	printf("d\n");
	_initFileSystemView();
	printf("e\n");
	_initMetaDataDisplay();
	printf("f\n");
	_initPlaylistView();
	printf("g\n");
	setCentralWidget(m_widget);
	setStatusBar(StatusBar::instance());
	
	
	_initSystemTray();
	
	_initActions();
	
	_initMenuBar();
	
	_initSignalsAndSlots();
}

void MainWindow::_initSignalsAndSlots(){
	//connect(m_player, SIGNAL(stateChanged(Player::State)), m_scrobbler, SLOT(slotPlayerStateChanged(Player::State)));
	//connect(m_player, SIGNAL(stateChanged(Player::State)), m_playlistView, SLOT(slotPlayerStateChanged(Player::State)));
	//connect(m_player, SIGNAL(stateChanged(Player::State)), this, SLOT(slotPlayerStateChanged(Player::State)));
	
	//connect(m_player, SIGNAL(metaDataChanged(QMultiMap<QString,QString>)), m_metaDataDisplay, SLOT(metaDataChanged(QMultiMap<QString,QString>)));
	
	//connect(m_player->playlist(), SIGNAL(nowPlaying(QPointer<Song>)), m_scrobbler, SLOT(slotNowPlaying(QPointer<Song>)));
	connect(m_player->playlist(), SIGNAL(songAdded(QPointer<Song>, short int)), m_leftPane, SLOT(slotSongAdded(QPointer<Song>)));
	connect(m_leftPane, SIGNAL(addSong(QPointer<Song>)), m_player->playlist(), SLOT(add(QPointer<Song>)));
	connect(m_leftPane, SIGNAL(addSongs(QList<QString>)), m_player->playlist(), SLOT(add(QList<QString>)));
	connect(m_playlistView, SIGNAL(addSongToPlaylist(QPointer<Song>,short int)), m_player->playlist(), SLOT(add(QPointer<Song>, short int)));
	connect(m_playlistView, SIGNAL(removeSongs(QList<short int>)), m_player->playlist(), SLOT(slotRemoveSongs(QList<short int>)));
	connect(m_player->playlist(), SIGNAL(songRemoved(short int)), m_playlistView, SLOT(slotSongRemoved(short int)));
	
	connect(m_actionPrev, SIGNAL(triggered()), m_player, SLOT(prev()));
	connect(m_actionPlayPause, SIGNAL(triggered()), m_player, SLOT(play()));
	connect(m_actionNext, SIGNAL(triggered()), m_player, SLOT(next()));
	connect(m_actionStop, SIGNAL(triggered()), m_player, SLOT(stop()));
	//connect(m_actionStopAfterCurrent, SIGNAL(triggered()), m_player, SLOT(stopAfterCurrent()));
	connect(m_actionStopAfterCurrent, SIGNAL(triggered()), m_playlistView, SLOT(stopAfterCurrent()));
	connect(m_actionQuit, SIGNAL(triggered()), this, SLOT(slotQuit()));
	connect(m_actionRestoreHide, SIGNAL(triggered()), this, SLOT(slotRestoreHide()));
	
	connect(m_actionAddMedia, SIGNAL(triggered()), this, SLOT(slotAddMedia()));
	connect(m_actionConfigure, SIGNAL(triggered()), this, SLOT(slotConfigure()));
	connect(m_actionPlaylistLoad, SIGNAL(triggered()), this, SLOT(slotPlaylistLoad()));
	connect(m_actionPlaylistSave, SIGNAL(triggered()), this, SLOT(slotPlaylistSave()));
	connect(m_actionAbout, SIGNAL(triggered()), this, SLOT(slotAbout()));
	connect(m_actionAboutQt, SIGNAL(triggered()), this, SLOT(slotAboutQt()));
	
	connect(m_playlistView, SIGNAL(requestedEditMetadata(QList<QString>)), this, SLOT(slotRequestedEditMetadata(QList<QString>)));
}

void MainWindow::_initPlayerController(){
	printf("a'\n");
	m_playerController = new PlayerController(m_topWidget, m_player);
	printf("a''\n");
	m_topLayout->addWidget(m_playerController);
	printf("a'''\n");
	//addDockWidget(Qt::RightDockWidgetArea, m_playerController->volumeDock());
	printf("a''''\n");
}

void MainWindow::_initScrobbler(){
	m_scrobbler = new Scrobbler(this);
}

void MainWindow::_initFileSystemView(){
	m_leftPane = new LeftPane(m_displayWidget);
	m_displayLayout->addWidget(m_leftPane);
}

void MainWindow::_initMetaDataDisplay(){
	m_metaDataDisplay = new MetaDataDisplay(m_displayWidget);
	m_displayLayout->addWidget(m_metaDataDisplay);
}

void MainWindow::_initPlaylistView(){
	m_playlistView = new PlaylistView(m_displayWidget);
	m_playlistView->setPlaylist(m_player->playlist());
	m_displayLayout->addWidget(m_playlistView);
}

void MainWindow::_initActions(){
	m_actionPrev = new QAction(QIcon::fromTheme("media-skip-backward"), "Prev", this);
	addAction(m_actionPrev);
	m_actionPrev->setShortcut(Qt::Key_MediaPrevious);
	m_actionPrev->setShortcutContext(Qt::ApplicationShortcut);
	
	m_actionPlayPause = new QAction(QIcon::fromTheme("media-playback-start"), "Play", this);
	addAction(m_actionPlayPause);
	m_actionPlayPause->setShortcut(Qt::Key_MediaPlay);
	m_actionPlayPause->setShortcutContext(Qt::ApplicationShortcut);
	
	m_actionNext = new QAction(QIcon::fromTheme("media-skip-forward"), "Next", this);
	addAction(m_actionNext);
	m_actionNext->setShortcut(Qt::Key_MediaNext);
	m_actionNext->setShortcutContext(Qt::ApplicationShortcut);
	
	m_actionStop = new QAction(QIcon::fromTheme("media-playback-stop"), "Stop", this);
	addAction(m_actionStop);
	m_actionStop->setShortcut(Qt::Key_MediaStop);
	m_actionStop->setShortcutContext(Qt::ApplicationShortcut);
	m_actionStop->setEnabled(false);//Because when the app starts, it's not yet playing.
	
	m_actionQuit = new QAction(QIcon::fromTheme("application-exit"), "Quit", this);
	addAction(m_actionQuit);
	
	m_actionRestoreHide = new QAction("Hide", this);
	addAction(m_actionRestoreHide);
	
	m_actionAddMedia = new QAction(QIcon::fromTheme("folder-open"), "Add Media...", this);
	addAction(m_actionAddMedia);
	
	m_actionStopAfterCurrent = new QAction(QIcon::fromTheme("media-playback-stop"), "Stop after current", this);
	addAction(m_actionStopAfterCurrent);
	
	m_actionConfigure = new QAction(QIcon::fromTheme("configure"), "Configure SQDP...", this);
	addAction(m_actionConfigure);
	
	m_actionPlaylistSave = new QAction(QIcon::fromTheme("document-save-as"), "Save Playlist...", this);
	addAction(m_actionPlaylistSave);
	
	m_actionPlaylistLoad = new QAction(QIcon::fromTheme("document-open"), "Load Playlist...", this);
	addAction(m_actionPlaylistLoad);
	
	m_actionAbout = new QAction(QIcon::fromTheme("media-playback-start"), "About SQDP", this);
	addAction(m_actionAbout);
	
	m_actionAboutQt = new QAction(QIcon::fromTheme(""), "About Qt", this );
	addAction(m_actionAboutQt);
	
	m_systemTrayIcon->addActions(m_actionPrev, m_actionPlayPause, m_actionNext, m_actionStop, m_actionQuit, m_actionRestoreHide, m_actionConfigure);
	m_playlistView->addPlayAction(m_actionPlayPause);
	m_playlistView->addStopAction(m_actionStop);
	m_playerController->addActions(m_actionPrev, m_actionPlayPause, m_actionNext, m_actionStop);
}

void MainWindow::_initMenuBar(){
	m_menuBar = new QMenuBar(this);
	setMenuBar(m_menuBar);
	
	QMenu *menu = m_menuBar->addMenu("SQDP");
	menu->addAction(m_actionAddMedia);
	menu->addSeparator();
	menu->addAction(m_actionPrev);
	menu->addAction(m_actionPlayPause);
	menu->addAction(m_actionStop);
	menu->addAction(m_actionStopAfterCurrent);
	menu->addAction(m_actionNext);
	menu->addSeparator();
	menu->addAction(m_actionQuit);
	
	menu = m_menuBar->addMenu("Playlist");
	menu->addAction(m_actionPlaylistSave);
	menu->addAction(m_actionPlaylistLoad);
	
	menu = m_menuBar->addMenu("Settings");
	menu->addAction(m_actionConfigure);
	
	menu = m_menuBar->addMenu("Help");
	menu->addAction(m_actionAbout);
	menu->addAction(m_actionAboutQt);
}

void MainWindow::_initSystemTray(){
	m_systemTrayIcon = new SystemTrayIcon(this);
}

MainWindow::~MainWindow(){
	printf("~MainWindow\n");
	if(Settings::instance()->general->usePlaylist)
		PlaylistWriter::write(m_player->playlist(), "xml", Settings::instance()->settingsDir() + ".playlist.xml");
}

/*void MainWindow::slotPlayerStateChanged(Player::State state){
	switch(state){
		case Player::Playing:
			m_actionPlayPause->setText("Pause");
			m_actionPlayPause->setIcon(QIcon::fromTheme("media-playback-pause"));
			m_actionStop->setEnabled(true);
			break;
		case Player::Paused:
			m_actionPlayPause->setText("Play");
			m_actionPlayPause->setIcon(QIcon::fromTheme("media-playback-start"));
			m_actionStop->setEnabled(true);
			break;
		case Player::Stopped:
			m_actionPlayPause->setText("Play");
			m_actionPlayPause->setIcon(QIcon::fromTheme("media-playback-start"));
			m_actionStop->setEnabled(false);
			break;
	}
}*/

void MainWindow::closeEvent( QCloseEvent *event ){
	if( isVisible() ){
		hide();
		event->ignore();
	}
}

void MainWindow::slotRestoreHide(){
	if( isVisible() ){
		hide();
		m_actionRestoreHide->setText("Restore");
	}else{
		show();
		m_actionRestoreHide->setText("Hide");
	}
}

void MainWindow::slotRequestedEditMetadata(QList<QString> songPaths){
	MetaDataEditor::launchEditor(songPaths);
}

//Probably the cleanest way of doing this, as this way MainWindows children appear to get deleted properly as well.
void MainWindow::slotQuit(){
	show();
	m_player->stop();
	qApp->setQuitOnLastWindowClosed(true);
	deleteLater();
}

void MainWindow::slotAddMedia(){//TODO This seems... Misplaced. The GUI processes Songs to be added to the Playlist to later end back in the GUI...
//TODO This does not accept directories either, kind of a shitty solution, but ah well. Will fix this later.
	QStringList files = QFileDialog::getOpenFileNames(this, "Add Media...", QDir::currentPath());
	m_playlistView->addMedia(files);
}

void MainWindow::slotConfigure(){
	SettingsDialog::show();
}

void MainWindow::slotPlaylistSave(){
	QString filename = QFileDialog::getSaveFileName(this, "Save Playlist", QDir::currentPath(), "Playlists (*.m3u *.xml)");
	if(filename.isEmpty())
		return;
	if(filename.endsWith(".xml")){
		PlaylistWriter::write(m_player->playlist(), "xml", filename);
		sStatusBar->log("Wrote playlist to " + filename);
	}else if(filename.endsWith(".m3u")){
		PlaylistWriter::write(m_player->playlist(), "m3u", filename);
		sStatusBar->log("Wrote playlist to " + filename);
	}else
		sStatusBar->log("Failed to save playlist to " + filename + ": unknown extention.");
// 	PlaylistReader::read(m_player->playlist(), filename);
}
	
void MainWindow::slotPlaylistLoad(){
	QString filename = QFileDialog::getOpenFileName(this, "Load Playlist", QDir::currentPath(), "Playlists (*.m3u *.xml)");
	if(filename.isEmpty())
		return;
	PlaylistReader::read(m_player->playlist(), filename);
}

void MainWindow::slotAbout(){
	QString text;
	text += "Simple Qt Desktop Player, an audio player built on Qt. It was made for educational purposes by Ruben van Haaster.\n";
	text += "\n";
	text += "Contact: rubenvanhaaster@live.com\n";
	text += "Homepage: code.google.com/p/simple-qt-desktop-player/";
	QMessageBox::about(this, "About SQDP", text);
}

void MainWindow::slotAboutQt(){
	QMessageBox::aboutQt(this, "About Qt");
}
